package qj.ps.sla.vfg;

import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import qj.util.IOUtil;

public class EspSimuServlet extends HttpServlet {
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println(req.getRequestURI());
		System.out.println(req.getQueryString());
		IOUtil.inputStreamToString(req.getInputStream());
//		String input = inputStreamToString(req.getInputStream());
//		String responseTmpl = inputStreamToString(EspSimuServlet.class.getResourceAsStream("RESPONSE.xml"));
//		
//		Map<String, String> values = EspSimuServlet.<String,String>map(
//				"applicationID", getValueXml("v1:applicationID", input),
//				"serviceID",getValueXml("v1:serviceID", input),
//				"serviceInterfaceVersion",getValueXml("v1:serviceInterfaceVersion", input),
//				"timestamp",getValueXml("v1:timestamp", input),
//				"referenceID",getValueXml("v1:referenceID", input),
//				"identityID",getValueXml("v1:identityID", input),
//				"resultCode","OK"
//				);
//
//		String reply = simpleTemplateApply(values, responseTmpl);
//		resp.getWriter().write(reply);
	}

	/**
	 * Get the value of xml node
	 * @param name
	 * @param input
	 * @return
	 */
	private String getValueXml(String name, String input) {
		return getString(Pattern.compile("<" + name + ">([^<]+)</" + name + ">"), 1, input);
	}

	/**
	 * Get the string group out of given text
	 * @param ptn
	 * @param groupId
	 * @param text
	 * @return
	 */
	public static String getString(Pattern ptn, int groupId, String text) {
		Matcher matcher = ptn.matcher(text);
		if (matcher.find()) {
			return matcher.group(groupId);
		} else {
			return null;
		}
	}

	/**
	 * Apply all the spaceholders like $name or $age with the values
	 * @param templateParams
	 * @param template
	 * @return
	 */
	public static String simpleTemplateApply(Map<String, String> templateParams, String template) {
		for (Entry<String, String> entry : templateParams.entrySet()) {
			template = template.replaceAll("\\$" + entry.getKey(), entry.getValue());
		}
		return template;
	}
	

    /**
     * Reads in whole input stream and returns as a string
     * @param in The input stream to read in, will be closed 
     * 				by this method at finish
     * @return the result string
     * @throws IOException
     */
	public static String inputStreamToString(InputStream in) throws IOException {
		return inputStreamToString(in, null);
	}

    /**
     * Reads in whole input stream and returns as a string
     * @param in The input stream to read in, will be closed 
     * 				by this method at finish
     * @param charSet charset to convert the input bytes into string
     * @return the result string
     * @throws IOException
     */
	public static String inputStreamToString(InputStream in, String charSet) throws IOException {
		try {
			BufferedReader br = new BufferedReader(
					charSet == null? new InputStreamReader(in) : new InputStreamReader(in, charSet)
					);
			StringBuffer sb = new StringBuffer();
			String tempRead;
			boolean first = true;
			while ((tempRead = br.readLine()) != null) {
				if (!first)
					sb.append('\n');
				sb.append(tempRead);
				if (first)
					first = false;
			}
			return sb.toString();
		} finally {
			close(in);
		}
	}

    /**
     * Close streams (in or out)
     * @param stream
     */
    public static void close(Closeable stream) {
        if (stream != null) {
            try {
                if (stream instanceof Flushable) {
                    ((Flushable)stream).flush();
                }
                stream.close();
            } catch (IOException e) {
                // When the stream is closed or interupted, can ignore this exception
            }
        }
    }

    /**
     * Create a map based on the Object... param. Each 2 values is an entry
     * which is a pair of key then value
     * @param objects
     * @return
     */
    @SuppressWarnings({"unchecked"})
    public static <A, B> Map<A, B> map(Object... objects) {
    	if (objects==null) {
    		return null;
    	}
    	
        Map<A, B> map = new HashMap<A, B>(objects.length / 2);
        for (int i = 0; i < objects.length; i+=2) {
            map.put((A)objects[i], (B)objects[i + 1]);
        }
        return map;
    }
}
